package org.aceor.mddal.gateway.merger.groupby;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import org.aceor.mddal.common.sqlparser.result.object.GroupByColumn;
import org.aceor.mddal.common.sqlparser.result.object.OrderByColumn;
import org.aceor.mddal.common.sqlparser.result.object.OrderByColumn.OrderByType;
import org.aceor.mddal.gateway.merger.common.ResultSetQueryIndex;
import org.aceor.mddal.gateway.util.ResultSetUtil;

import java.util.List;
import java.util.Map;

/**
 * 表示一行记录,和AggregateValue一致
 * Created by lxue on 16/4/16.
 */
public class GroupByValue implements Comparable<GroupByValue>{

    private Map<Integer, Object> rowSetIndexMap = Maps.newLinkedHashMap();
    private Map<String/** upperCase **/, Object> rowSetColumnNameMap = Maps.newLinkedHashMap();

    private List<GroupByColumn> groupByColumnList;
    private List<OrderByColumn> orderByColumnList;

    public Object getValue(ResultSetQueryIndex resultSetQueryIndex) {

        if (resultSetQueryIndex.isQueryByIndex()) {
            return rowSetIndexMap.get(resultSetQueryIndex.getQueryIndex());
        } else {
            return rowSetColumnNameMap.get(((String) resultSetQueryIndex.getQueryName().toUpperCase()));
        }

    }

    public void put(int index, String columnName, Object object) {
        Preconditions.checkArgument(index > 0);
        Preconditions.checkArgument(!Strings.isNullOrEmpty(columnName));
        Preconditions.checkNotNull(object);
        rowSetColumnNameMap.put(columnName.toUpperCase(), object);
        rowSetIndexMap.put(index, object);
    }

    public void setGroupByColumnList(List<GroupByColumn> groupByColumnList) {
        this.groupByColumnList = groupByColumnList;
    }

    public void setOrderByColumnList(List<OrderByColumn> orderByColumnList) {
        this.orderByColumnList = orderByColumnList;
    }

    private Object getValueByName(String name) {
        return rowSetColumnNameMap.get(name.toUpperCase());
    }
    @Override
    public int compareTo(final GroupByValue other) {
        if (null == other) {
            return -1;
        }
        if (orderByColumnList.isEmpty()) {
            return compareFromGroupByColumns(other);
        }
        return compareFromOrderByColumns(other);
    }

    private int compareFromOrderByColumns(final GroupByValue other) {
        for (OrderByColumn each : orderByColumnList) {
            OrderByType orderByType = null == each.getOrderByType() ? OrderByType.ASC : each.getOrderByType();
            Object thisValue = getValueByName(each.getName());
            Object otherValue = other.getValueByName(each.getName());
            int result = ResultSetUtil.compareTo(thisValue, otherValue, orderByType);
            if (0 != result) {
                return result;
            }
        }
        return 0;
    }

    private int compareFromGroupByColumns(final GroupByValue other) {
        for (GroupByColumn each : groupByColumnList) {
            OrderByType orderByType = null == each.getOrderByType() ? OrderByType.ASC : each.getOrderByType();
            Object thisValue = getValueByName(each.getName());
            Object otherValue = other.getValueByName(each.getName());
            int result = ResultSetUtil.compareTo(thisValue, otherValue, orderByType);
            if (0 != result) {
                return result;
            }
        }
        return 0;
    }
}
